ROS2 分层架构与 ROS1 对比
ROS2 虽然常被称作"机器人操作系统",但它并不是传统意义上的操作系统,而是一套构建机器人应用程序的开发工具包,必须运行在常规操作系统之上。本文梳理 ROS2 的三层结构——每层由什么组成、承担什么职责,给出 rmw 抽象层的 API 分类速查,并与 ROS1 对比说明架构上的关键差异。适合初次接触 ROS2、想先建立整体框架认知再深入各组件的读者。
三层总览
| 层 | 组成 | 职责 |
|---|---|---|
| 操作系统层 | Linux、Windows、macOS、RTOS | 提供进程调度、内存、网络等基础能力 |
| 中间层 | 客户端库、rcl、rmw 抽象层、DDS 实现、进程内通讯 | 节点发现与数据传输 |
| 应用层 | 功能包 | 开发者构建的机器人业务逻辑 |
操作系统层
ROS2 对操作系统的依赖仅限常规的进程、线程、网络能力,因此可以运行在多种系统上:Linux(Ubuntu)是一级支持平台,Windows 与 macOS 为随版本滚动支持的平台;实时操作系统(RTOS)通过 micro-ROS 方案接入,支持 FreeRTOS、Zephyr、NuttX 等。跨平台能力是 ROS2 相对 ROS1 的一个显著扩展。
中间层
中间层是 ROS2 架构变化最大的部分,主要由以下组件构成:
- DDS(数据分发服务):一种去中心化的发布订阅通信服务,没有中心节点,节点发现由参与者之间直接完成。ROS2 借助 DDS 在较差网络环境下仍能维持通信,依靠的是可配置的服务质量(QoS)机制:可靠性、时限、历史深度等策略都可以按链路情况调整。
- 客户端库:面向开发者的 API 层。C++ 的 rclcpp 与 Python 的 rclpy 都构建在语言无关的 rcl 核心之上(官方文档原文:"rclcpp builds on top of rcl and the rosidl API"),各语言特有的功能(如 spin 的线程模型)留在各自的客户端库里实现。
- rmw 抽象层:客户端库不直接依赖某个具体的 DDS 产品,而是通过 rmw 接口调用;每种 DDS 实现提供一个 rmw 包(如 rmw_fastrtps、rmw_cyclonedds)。官方文档说明:目前的 ROS2 中间件实现"全部基于完整或部分的 DDS 实现"。这让 DDS 实现可以在构建期切换,而应用代码不变。
- 进程内通讯:同一进程内的发布方与订阅方可以走进程内通道直接传递消息,避免序列化与网络栈开销。
rmw 层的 API 面
rmw 层对上提供的是一套 C API(extern "C" 接口),功能按组划分:初始化与关闭(管理 RMW 实例生命周期)、节点管理、通信原语(发布订阅、服务客户端)、同步机制(wait set 与 guard condition)、图查询、QoS 配置、序列化。常用接口速查:
| 类别 | 功能 | 示例函数 |
|---|---|---|
| 初始化 | 设置并配置中间件 | rmw_init(), rmw_shutdown() |
| 节点管理 | 创建和管理 ROS 节点 | rmw_create_node(), rmw_destroy_node() |
| 发布器 | 创建和使用消息发布器 | rmw_create_publisher(), rmw_publish() |
| 订阅器 | 创建和使用消息订阅器 | rmw_create_subscription(), rmw_take() |
| 服务端 | 实现请求-响应服务端 | rmw_create_service(), rmw_take_request() |
| 客户端 | 实现请求-响应客户端 | rmw_create_client(), rmw_send_request() |
| 等待集合 | 多实体活动监控与等待 | rmw_create_wait_set(), rmw_wait() |
| 拓扑查询 | ROS 通信图查询 | rmw_get_node_names(), rmw_count_publishers() |
| 校验验证 | 验证名称和标识符规范性 | rmw_validate_full_topic_name(), rmw_validate_namespace() |
| 服务质量 | 配置通信质量策略 | rmw_qos_profile_check_compatible() |
这张表的意义在于展示 rmw 层的职责边界:客户端库(rclcpp/rclpy)的功能最终都落到这些函数的某种组合上,而每种 DDS 实现负责给出它们各自的适配。其中序列化相关接口(rmw_serialize / rmw_deserialize)与消息管线的细节,见本站《ROS2 消息序列化:从 .msg 到 CDR 字节流》。
应用层
应用层是开发者构建的应用程序,以功能包为组织单位:功能包中包含源码、消息与服务等数据定义、对外接口等内容。这一层的组织方式与 ROS1 一脉相承。
与 ROS1 的关键差异
| 维度 | ROS1 | ROS2 |
|---|---|---|
| 中心节点 | 依赖 Master(roscore),单点故障 | 无 Master,DDS 分布式发现 |
| 通信协议 | TCPROS / UDPROS 自研协议 | DDS,rmw 层可替换实现 |
| 通信策略 | 行为基本固定 | QoS 可配置(可靠性、时限、历史深度等) |
| 平台 | 主要运行于 Linux | Linux、Windows、macOS、RTOS |
| 多机通信 | 依赖 Master 的集中式发现 | 分布式发现,多机场景无需额外中心组件 |
其中影响最深远的是去掉了 Master:ROS1 里所有节点都要先向 Master 注册、通过 Master 相识,Master 退出整个系统就瘫痪;ROS2 把发现与数据面都交给 DDS,节点之间对等通信,多机、多机器人场景不需要额外的中心组件。
小结
- ROS2 是开发工具包而非操作系统,三层中变化集中在中间层:DDS 接管通信与发现,rmw 保证 DDS 可替换。
- rmw 层的 API 面覆盖初始化、节点、通信原语、等待、图查询、QoS 与序列化,客户端库的功能最终都落到这组 C 接口的组合上。
- 无 Master 的分布式发现与可配置 QoS 是 ROS2 相对 ROS1 最核心的两个架构差异。
- 跨平台(含 RTOS)支持让同一套应用代码可以覆盖从工作站到嵌入式实时设备的部署范围。
参考:REP 2000(目标平台) · Client Libraries(humble 文档) · Middleware Implementations(humble 文档) · ROS on DDS(设计文) · micro-ROS